package com.tutorial.springboot.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 自定义RDS数据源；采用JPA事务管理
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.tutorial.springboot.repository"})
public class JpaConfig implements TransactionManagementConfigurer {

    @Value("${spring.dataSource.driver}")
    private String DB_DRIVER;

    @Value("${spring.dataSource.password}")
    private String DB_PASSWORD;

    @Value("${spring.dataSource.url}")
    private String DB_URL;

    @Value("${spring.dataSource.username}")
    private String DB_USERNAME;

    @Value("${spring.hibernate.dialect}")
    private String HIBERNATE_DIALECT;

    @Value("${spring.hibernate.show_sql}")
    private String HIBERNATE_SHOW_SQL;

    @Value("${spring.hibernate.hbm2ddl_auto}")
    private String HIBERNATE_HBM2DDL_AUTO;

    @Value("${spring.hibernate.packagesToScan}")
    private String ENTITYMANAGER_PACKAGES_TO_SCAN;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(DB_DRIVER);
        dataSource.setUrl(DB_URL);
        dataSource.setUsername(DB_USERNAME);
        dataSource.setPassword(DB_PASSWORD);

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

        Properties jpaProperties = new Properties();
        jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, HIBERNATE_DIALECT);
        jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, HIBERNATE_HBM2DDL_AUTO);
        jpaProperties.put(org.hibernate.cfg.Environment.SHOW_SQL, HIBERNATE_SHOW_SQL);
        entityManagerFactoryBean.setJpaProperties(jpaProperties);

        return entityManagerFactoryBean;
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new JpaTransactionManager();
    }
}

